﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using nBayes;

namespace MailClient.Data.IndexTables
{
    // Lazy construction of classes to use as static classes
    // for the bayesian filter. these are type safe, so we
    // can call from multiple threads. each must implement IFilter
    interface IFilter : IDisposable
    {

    }

    /// <summary>
    /// Gets the spam index for the bayesian filter
    /// </summary>
    public sealed class SpamIndex : FileIndex, IFilter
    {
        // with the static keyword on the constructor this should
        // keep the object in memory for the lifetime of the application
        private static readonly Lazy<SpamIndex> lazy =
            new Lazy<SpamIndex>(() => new SpamIndex());
        private static object synclock = new object();

        public static SpamIndex Index { get { return lazy.Value; } }

        public override void Add(Entry document)
        {
            lock (synclock)
                base.Add(document);
        }

        public override int EntryCount
        {
            get
            {
                lock (synclock)
                {
                    return base.EntryCount;
                }
            }
        }

        public override int GetTokenCount(string token)
        {
            lock (synclock)
                return base.GetTokenCount(token);
        }

        public void Save()
        {
            lock (synclock)
                base.Save();
        }

        public void Dispose()
        {
            lock (synclock)
                base.Save();
            // GC.ReRegisterForFinalize(this);
        }

        private SpamIndex()
            : base(MailClient.Properties.Settings.Default.SPAMPATH)
        {
            lock (synclock)
                Open();
            /* 
             * Per MSDN SuppressFinalize exmepts objects from finalization
             * this means that during shutdown the deconstructor won't be called
             */
            //  GC.SuppressFinalize(this);
        }

        ~SpamIndex()
        {
            Dispose();
        }
    }

    public sealed class NotSpamIndex : FileIndex, IFilter
    {
        private static readonly Lazy<NotSpamIndex> lazy =
            new Lazy<NotSpamIndex>(() => new NotSpamIndex());
        private static object synclock = new object();

        public static NotSpamIndex Index { get { return lazy.Value; } }

        public override void Add(Entry document)
        {
            lock (synclock)
                base.Add(document);
        }

        public override int EntryCount
        {
            get
            {
                lock (synclock)
                {
                    return base.EntryCount;
                }
            }
        }

        public override int GetTokenCount(string token)
        {
            lock (synclock)
                return base.GetTokenCount(token);
        }

        public void Save()
        {
            lock (synclock)
                base.Save();
        }


        public void Dispose()
        {
            lock (synclock)
                Save();

        }

        private NotSpamIndex()
            : base(MailClient.Properties.Settings.Default.NOTSPAMPATH)
        {
            lock (synclock)
                Open();

        }

        ~NotSpamIndex()
        {
            Dispose();
        }
    }

    public sealed class MerchIndex : FileIndex, IFilter
    {
        private static readonly Lazy<MerchIndex> lazy =
            new Lazy<MerchIndex>(() => new MerchIndex());
        private static object synclock = new object();

        public static MerchIndex Index { get { return lazy.Value; } }

        public override void Add(Entry document)
        {
            lock (synclock)
                base.Add(document);
        }

        public override int EntryCount
        {
            get
            {
                lock (synclock)
                {
                    return base.EntryCount;
                }
            }
        }

        public override int GetTokenCount(string token)
        {
            lock (synclock)
                return base.GetTokenCount(token);
        }

        public void Save()
        {
            lock (synclock)
                base.Save();
        }


        public void Dispose()
        {
            lock (synclock)
                Save();

        }

        private MerchIndex()
            : base(MailClient.Properties.Settings.Default.PMERCH)
        {
            lock (synclock)
                Open();

        }

        ~MerchIndex()
        {
            Dispose();
        }
    }

    public sealed class BrandIndex : FileIndex, IFilter
    {
        private static readonly Lazy<BrandIndex> lazy =
            new Lazy<BrandIndex>(() => new BrandIndex());
        private static object synclock = new object();

        public static BrandIndex Index { get { return lazy.Value; } }

        public override void Add(Entry document)
        {
            lock (synclock)
                base.Add(document);
        }

        public override int EntryCount
        {
            get
            {
                lock (synclock)
                {
                    return base.EntryCount;
                }
            }
        }

        public override int GetTokenCount(string token)
        {
            lock (synclock)
                return base.GetTokenCount(token);
        }

        public void Save()
        {
            lock (synclock)
                base.Save();
        }


        public void Dispose()
        {
            lock (synclock)
                Save();

        }

        private BrandIndex()
            : base(MailClient.Properties.Settings.Default.PBRC)
        {
            lock (synclock)
                Open();

        }

        ~BrandIndex()
        {
            Dispose();
        }
    }

    public sealed class CityIndex : FileIndex, IFilter
    {
        private static readonly Lazy<CityIndex> lazy =
            new Lazy<CityIndex>(() => new CityIndex());
        private static object synclock = new object();

        public static CityIndex Index { get { return lazy.Value; } }

        public override void Add(Entry document)
        {
            lock (synclock)
                base.Add(document);
        }

        public override int EntryCount
        {
            get
            {
                lock (synclock)
                {
                    return base.EntryCount;
                }
            }
        }

        public override int GetTokenCount(string token)
        {
            lock (synclock)
                return base.GetTokenCount(token);
        }

        public void Save()
        {
            lock (synclock)
                base.Save();
        }


        public void Dispose()
        {
            lock (synclock)
                Save();

        }

        private CityIndex()
            : base(MailClient.Properties.Settings.Default.PCITY)
        {
            lock (synclock)
                Open();

        }

        ~CityIndex()
        {
            Dispose();
        }
    }

    public sealed class CivilIndex : FileIndex, IFilter
    {
        private static readonly Lazy<CivilIndex> lazy =
            new Lazy<CivilIndex>(() => new CivilIndex());
        private static object synclock = new object();

        public static CivilIndex Index { get { return lazy.Value; } }

        public override void Add(Entry document)
        {
            lock (synclock)
                base.Add(document);
        }

        public override int EntryCount
        {
            get
            {
                lock (synclock)
                {
                    return base.EntryCount;
                }
            }
        }

        public override int GetTokenCount(string token)
        {
            lock (synclock)
                return base.GetTokenCount(token);
        }

        public void Save()
        {
            lock (synclock)
                base.Save();
        }


        public void Dispose()
        {
            lock (synclock)
                Save();

        }

        private CivilIndex()
            : base(MailClient.Properties.Settings.Default.PDCIVIL)
        {
            lock (synclock)
                Open();

        }

        ~CivilIndex()
        {
            Dispose();
        }
    }

    public sealed class FuelIndex : FileIndex, IFilter
    {
        private static readonly Lazy<FuelIndex> lazy =
            new Lazy<FuelIndex>(() => new FuelIndex());
        private static object synclock = new object();

        public static FuelIndex Index { get { return lazy.Value; } }

        public override void Add(Entry document)
        {
            lock (synclock)
                base.Add(document);
        }

        public override int EntryCount
        {
            get
            {
                lock (synclock)
                {
                    return base.EntryCount;
                }
            }
        }

        public override int GetTokenCount(string token)
        {
            lock (synclock)
                return base.GetTokenCount(token);
        }

        public void Save()
        {
            lock (synclock)
                base.Save();
        }


        public void Dispose()
        {
            lock (synclock)
                Save();

        }

        private FuelIndex()
            : base(MailClient.Properties.Settings.Default.PFUEL)
        {
            lock (synclock)
                Open();

        }

        ~FuelIndex()
        {
            Dispose();
        }
    }

    public sealed class GeoIndex : FileIndex, IFilter
    {
        private static readonly Lazy<GeoIndex> lazy =
            new Lazy<GeoIndex>(() => new GeoIndex());
        private static object synclock = new object();

        public static GeoIndex Index { get { return lazy.Value; } }

        public override void Add(Entry document)
        {
            lock (synclock)
                base.Add(document);
        }

        public override int EntryCount
        {
            get
            {
                lock (synclock)
                {
                    return base.EntryCount;
                }
            }
        }

        public override int GetTokenCount(string token)
        {
            lock (synclock)
                return base.GetTokenCount(token);
        }

        public void Save()
        {
            lock (synclock)
                base.Save();
        }


        public void Dispose()
        {
            lock (synclock)
                Save();

        }

        private GeoIndex()
            : base(MailClient.Properties.Settings.Default.PGEO)
        {
            lock (synclock)
                Open();

        }

        ~GeoIndex()
        {
            Dispose();
        }
    }

    public sealed class ShellIndex : FileIndex, IFilter
    {
        private static readonly Lazy<ShellIndex> lazy =
            new Lazy<ShellIndex>(() => new ShellIndex());
        private static object synclock = new object();

        public static ShellIndex Index { get { return lazy.Value; } }

        public override void Add(Entry document)
        {
            lock (synclock)
                base.Add(document);
        }

        public override int EntryCount
        {
            get
            {
                lock (synclock)
                {
                    return base.EntryCount;
                }
            }
        }

        public override int GetTokenCount(string token)
        {
            lock (synclock)
                return base.GetTokenCount(token);
        }

        public void Save()
        {
            lock (synclock)
                base.Save();
        }


        public void Dispose()
        {
            lock (synclock)
                Save();

        }

        private ShellIndex()
            : base(MailClient.Properties.Settings.Default.PSHELL)
        {
            lock (synclock)
                Open();

        }

        ~ShellIndex()
        {
            Dispose();
        }
    }

    public sealed class WaterIndex : FileIndex, IFilter
    {
        private static readonly Lazy<WaterIndex> lazy =
            new Lazy<WaterIndex>(() => new WaterIndex());
        private static object synclock = new object();

        public static WaterIndex Index { get { return lazy.Value; } }

        public override void Add(Entry document)
        {
            lock (synclock)
                base.Add(document);
        }

        public override int EntryCount
        {
            get
            {
                lock (synclock)
                {
                    return base.EntryCount;
                }
            }
        }

        public override int GetTokenCount(string token)
        {
            lock (synclock)
                return base.GetTokenCount(token);
        }

        public void Save()
        {
            lock (synclock)
                base.Save();
        }


        public void Dispose()
        {
            lock (synclock)
                Save();

        }

        private WaterIndex()
            : base(MailClient.Properties.Settings.Default.PWATER)
        {
            lock (synclock)
                Open();

        }

        ~WaterIndex()
        {
            Dispose();
        }
    }

    public sealed class StoreIndex : FileIndex, IFilter
    {
        private static readonly Lazy<StoreIndex> lazy =
            new Lazy<StoreIndex>(() => new StoreIndex());
        private static object synclock = new object();

        public static StoreIndex Index { get { return lazy.Value; } }

        public override void Add(Entry document)
        {
            lock (synclock)
                base.Add(document);
        }

        public override int EntryCount
        {
            get
            {
                lock (synclock)
                {
                    return base.EntryCount;
                }
            }
        }

        public override int GetTokenCount(string token)
        {
            lock (synclock)
                return base.GetTokenCount(token);
        }

        public void Save()
        {
            lock (synclock)
                base.Save();
        }


        public void Dispose()
        {
            lock (synclock)
                Save();

        }

        private StoreIndex()
            : base(MailClient.Properties.Settings.Default.PSTORE)
        {
            lock (synclock)
                Open();

        }

        ~StoreIndex()
        {
            Dispose();
        }
    }

    public sealed class PersonIndex : FileIndex, IFilter
    {
        private static readonly Lazy<PersonIndex> lazy =
            new Lazy<PersonIndex>(() => new PersonIndex());
        private static object synclock = new object();

        public static PersonIndex Index { get { return lazy.Value; } }

        public override void Add(Entry document)
        {
            lock (synclock)
                base.Add(document);
        }

        public override int EntryCount
        {
            get
            {
                lock (synclock)
                {
                    return base.EntryCount;
                }
            }
        }

        public override int GetTokenCount(string token)
        {
            lock (synclock)
                return base.GetTokenCount(token);
        }

        public void Save()
        {
            lock (synclock)
                base.Save();
        }


        public void Dispose()
        {
            lock (synclock)
                Save();

        }

        private PersonIndex()
            : base(MailClient.Properties.Settings.Default.PPERSON)
        {
            lock (synclock)
                Open();

        }

        ~PersonIndex()
        {
            Dispose();
        }
    }
}
